package com.hunt.service.app.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hunt.model.app.CollectStock;
import com.hunt.model.app.CollectStockGroup;
import com.hunt.model.app.CollectStockGroupVo;
import com.hunt.model.app.RealTimeSimpleStockData;
import com.hunt.model.entity.StockBase;
import com.hunt.service.app.CollectStockService;
import com.hunt.util.Result;
import com.mongodb.WriteResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

@Service
@Transactional
public class CollectStockServiceImpl implements CollectStockService {

    private static final Logger log = LoggerFactory.getLogger(CollectStockServiceImpl.class);

    @Autowired
    private MongoTemplate mongoTemplate;
    @Resource
    private RedisTemplate stringredisTemplate;

    //仅查询分组信息
    @Override
    public List<CollectStockGroupVo> onlyFindCollectStockGroupList(String userId, String stockBase) {

        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(userId));
        CollectStock collectStock = mongoTemplate.findOne(query, CollectStock.class, "collectStock");
        List<CollectStockGroupVo> list = new ArrayList<>();

        StockBase stockInfo = null;
        if (!stockBase.equals("")) {
            stockInfo = JSON.parseObject(stockBase, StockBase.class);
        }
        //单纯的分组列表功能 或者 编辑所属分组功能(组对象提示是否包含传入的股票代码)
        if (null != collectStock) {
            String id = collectStock.get_id();
            List<CollectStockGroup> groupList = collectStock.getGroupList();
            if (groupList.size() > 0) {
                for (CollectStockGroup stockGroup : groupList) {
                    CollectStockGroupVo vo = new CollectStockGroupVo();
                    if (stockInfo != null) {
                        List<StockBase> stockList = stockGroup.getStockList();
                        if (stockList.contains(stockInfo)) {
                            vo.setContains(true);
                        }
                    }
                    vo.set_id(id);
                    vo.setUserId(userId);
                    vo.setGroupId(stockGroup.getGroupId());
                    vo.setGroupName(stockGroup.getGroupName());
                    list.add(vo);
                }
            } else {
                CollectStockGroup collectStockGroup = new CollectStockGroup();
                collectStockGroup.setGroupId("Default");
                collectStockGroup.setGroupName("自选");
                groupList.add(collectStockGroup);
                collectStock.setGroupList(groupList);
                Update set = Update.update("_id", userId).set("groupList", collectStock.getGroupList());
                mongoTemplate.updateFirst(query, set, CollectStock.class, "collectStock");

                CollectStockGroupVo vo = new CollectStockGroupVo();
                vo.set_id(userId);
                vo.setUserId(userId);
                vo.setGroupName("自选");
                vo.setGroupId("Default");
                list.add(vo);
            }
        }
        return list;
    }

    //根据userId,goupId查询自选集合
    @Override
    public CollectStock findCollectStockGroupInfo(String userId, String groupId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(userId));
        CollectStock collectStock = mongoTemplate.findOne(query, CollectStock.class, "collectStock");
        //添加过自选
        if (null != collectStock) {
            List<CollectStockGroup> groupList = collectStock.getGroupList();
            if (groupList.size() > 0) {
                List<CollectStockGroup> resultGroupList = new ArrayList<>();
                if (groupId.equals("")) {
                    for (CollectStockGroup stockGroup : groupList) {
                        if (stockGroup.getGroupId().equals("Default")) {
                            resultGroupList.add(stockGroup);
                            collectStock.setGroupList(resultGroupList);
                            break;
                        }
                    }
                } else {
                    for (CollectStockGroup stockGroup : groupList) {
                        if (stockGroup.getGroupId().equals(groupId)) {
                            resultGroupList.add(stockGroup);
                            collectStock.setGroupList(resultGroupList);
                            break;
                        }
                    }
                }
            } else {
                List<CollectStockGroup> resultGroupList = new ArrayList<>();
                CollectStockGroup collectStockGroup = new CollectStockGroup();
                collectStockGroup.setGroupId("Default");
                collectStockGroup.setGroupName("自选");
                resultGroupList.add(collectStockGroup);
                collectStock.setGroupList(resultGroupList);
                Update set = Update.update("_id", userId).set("groupList", collectStock.getGroupList());
                mongoTemplate.updateFirst(query, set, CollectStock.class, "collectStock");
            }
        } else {
            CollectStock newCollectStock = new CollectStock();
            newCollectStock.set_id(userId);
            newCollectStock.setUserId(userId);
            List<CollectStockGroup> resultGroupList = new ArrayList<>();
            CollectStockGroup collectStockGroup = new CollectStockGroup();
            collectStockGroup.setGroupId("Default");
            collectStockGroup.setGroupName("自选");
            resultGroupList.add(collectStockGroup);
            newCollectStock.setGroupList(resultGroupList);
            mongoTemplate.insert(newCollectStock, "collectStock");
            return newCollectStock;
        }
        return collectStock;
    }

    //添加分组
    @Override
    public Result addCollectStockGroup(String userId, String groupName, String stockInfo) {
        StockBase stockBase = null;
        if (!stockInfo.equals("")) {
            stockBase = JSON.parseObject(stockInfo, StockBase.class);
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(userId));
        CollectStock collectStock = mongoTemplate.findOne(query, CollectStock.class, "collectStock");
        CollectStockGroup collectStockGroup;
        CollectStockGroupVo vo;
        //如果添加过自选
        if (null != collectStock) {
            List<CollectStockGroup> sourceGroupList = collectStock.getGroupList();
            if (sourceGroupList.size() > 0) {
                collectStockGroup = new CollectStockGroup();
                collectStockGroup.setGroupId(UUID.randomUUID().toString().replaceAll("-", ""));
                collectStockGroup.setGroupName(groupName);
                if (stockBase != null) {
                    collectStockGroup.getStockList().add(stockBase);
                }
                sourceGroupList.add(collectStockGroup);
            } else {
                CollectStockGroup defaultGroup = new CollectStockGroup();
                defaultGroup.setGroupId("Default");
                defaultGroup.setGroupName("自选");
                sourceGroupList.add(defaultGroup);

                collectStockGroup = new CollectStockGroup();
                collectStockGroup.setGroupId(UUID.randomUUID().toString().replaceAll("-", ""));
                collectStockGroup.setGroupName(groupName);
                if (stockBase != null) {
                    collectStockGroup.getStockList().add(stockBase);
                }
                sourceGroupList.add(collectStockGroup);
            }
            Update set = Update.update("_id", userId).set("groupList", sourceGroupList);
            boolean b = mongoTemplate.updateFirst(query, set, CollectStock.class, "collectStock").isUpdateOfExisting();
            if (b) {
                vo = new CollectStockGroupVo();
                vo.set_id(userId);
                vo.setUserId(userId);
                vo.setGroupId(collectStockGroup.getGroupId());
                vo.setGroupName(groupName);
                return Result.success(vo);
            } else {
                return Result.error(null);
            }

        } else {
            //如果没添加过自选股
            CollectStock newCollectStock = new CollectStock();
            newCollectStock.set_id(userId);
            newCollectStock.setUserId(userId);

            List<CollectStockGroup> groupList = new ArrayList<>();
            CollectStockGroup defaultGroup = new CollectStockGroup();
            defaultGroup.setGroupId("Default");
            defaultGroup.setGroupName("自选");
            groupList.add(defaultGroup);

            collectStockGroup = new CollectStockGroup();
            collectStockGroup.setGroupId(UUID.randomUUID().toString().replaceAll("-", ""));
            collectStockGroup.setGroupName(groupName);
            if (stockBase != null) {
                collectStockGroup.getStockList().add(stockBase);
            }
            groupList.add(collectStockGroup);
            newCollectStock.setGroupList(groupList);

            try {
                mongoTemplate.insert(newCollectStock, "collectStock");
            } catch (Exception e) {
                e.printStackTrace();
                return Result.error(null);
            }
            vo = new CollectStockGroupVo();
            vo.set_id(userId);
            vo.setUserId(userId);
            vo.setGroupId(collectStockGroup.getGroupId());
            vo.setGroupName(groupName);
            return Result.success(vo);
        }
    }

    //添加自选
    @Override
    public boolean addCollectStock2Group(String userId, String groupId, String stockInfo) {
        boolean b = false;
        StockBase stockBase = JSON.parseObject(stockInfo, StockBase.class);
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(userId));
        CollectStock collectStock = mongoTemplate.findOne(query, CollectStock.class, "collectStock");
        //如果添加过自选
        if (null != collectStock) {
            List<CollectStockGroup> groupList = collectStock.getGroupList();
            if (groupList.size() > 0) {
                for (CollectStockGroup stockGroup : groupList) {
                    if (groupId.equals("")) {
                        if (stockGroup.getGroupId().equals("Default")) {
                            stockGroup.getStockList().add(0, stockBase);
                            break;
                        }
                    } else {
                        if (stockGroup.getGroupId().equals(groupId)) {
                            stockGroup.getStockList().add(0, stockBase);
                            break;
                        }
                    }
                }
            } else {
                List<CollectStockGroup> newGroupList = new ArrayList<>();
                CollectStockGroup collectStockGroup = new CollectStockGroup();
                collectStockGroup.setGroupId("Default");
                collectStockGroup.setGroupName("自选");
                collectStockGroup.getStockList().add(0, stockBase);
                newGroupList.add(collectStockGroup);
                collectStock.setGroupList(newGroupList);
            }


            Update set = Update.update("_id", userId).set("groupList", collectStock.getGroupList());
            try {
                b = mongoTemplate.updateFirst(query, set, "collectStock").isUpdateOfExisting();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return b;

        } else {
            //如果没添加过自选
            CollectStock newCollectStock = new CollectStock();
            newCollectStock.set_id(userId);
            newCollectStock.setUserId(userId);
            List<CollectStockGroup> groupList = new ArrayList<>();
            CollectStockGroup collectStockGroup = new CollectStockGroup();
            collectStockGroup.setGroupId("Default");
            collectStockGroup.setGroupName("自选");
            collectStockGroup.getStockList().add(0, stockBase);
            groupList.add(collectStockGroup);
            newCollectStock.setGroupList(groupList);
            try {
                mongoTemplate.insert(newCollectStock, "collectStock");
                b = true;
            } catch (Exception e) {
                e.printStackTrace();
                return b;
            }
        }
        return b;
    }

    @Override
    public Result operationWithinGroup(String userId, String group) {
        CollectStockGroup collectStockGroup;
        try {
            collectStockGroup = JSONObject.parseObject(group, CollectStockGroup.class);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.param_format_error();
        }

        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(userId));
        CollectStock collectStock = mongoTemplate.findOne(query, CollectStock.class, "collectStock");
        List<CollectStockGroup> groupList = collectStock.getGroupList();
        for (int i = 0; i < groupList.size(); i++) {
            if (groupList.get(i).getGroupId().equals(collectStockGroup.getGroupId())) {
                groupList.set(i, collectStockGroup);
                break;
            }
        }
        Update set = Update.update("_id", userId).set("groupList", groupList);
        boolean b;
        try {
            b = mongoTemplate.updateFirst(query, set, "collectStock").isUpdateOfExisting();
            if (b) {
                return Result.success();
            } else {
                return Result.error();
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error();
        }
    }

    @Override
    public Result operationGroup(String userId, String groupList) {
        List<CollectStockGroupVo> groupVoList;
        try {
            groupVoList = JSONArray.parseArray(groupList, CollectStockGroupVo.class);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.param_format_error();
        }

        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(userId));
        CollectStock collectStock = mongoTemplate.findOne(query, CollectStock.class, "collectStock");
        List<CollectStockGroup> newGroupList = new ArrayList<>();
        for (CollectStockGroupVo groupVo : groupVoList) {
            CollectStockGroup collectStockGroup = new CollectStockGroup();
            collectStockGroup.setGroupName(groupVo.getGroupName());
            collectStockGroup.setGroupId(groupVo.getGroupId());
            for (CollectStockGroup oldGroup : collectStock.getGroupList()) {
                if (groupVo.getGroupId().equals(oldGroup.getGroupId())) {
                    collectStockGroup.setStockList(oldGroup.getStockList());
                    break;
                }
            }
            newGroupList.add(collectStockGroup);
        }
        collectStock.setGroupList(newGroupList);
        Update set = Update.update("_id", userId).set("groupList", newGroupList);

        boolean b;
        try {
            b = mongoTemplate.updateFirst(query, set, CollectStock.class, "collectStock").isUpdateOfExisting();
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error();
        }
        if (b) {
            return Result.success(collectStock);
        } else {
            return Result.error();
        }
    }

    /*@Override
    public boolean syncStock2Group(String userId,String stockInfo, List<CollectStockGroupVo> groupList) {
        StockBase stockBase = JSON.parseObject(stockInfo,StockBase.class);
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(userId));
        CollectStock collectStock = mongoTemplate.findOne(query, CollectStock.class, "collectStock");
        List<CollectStockGroup> oldGroupList = collectStock.getGroupList();

        for (CollectStockGroupVo groupVo : groupList) {
            String groupId = groupVo.getGroupId();
            boolean contains = groupVo.isContains();

            for (CollectStockGroup oldGroup : oldGroupList) {
                if (oldGroup.getGroupId().equals(groupId)){
                    if (contains){
                        if (!oldGroup.getStockList().contains(stockBase)){
                            oldGroup.getStockList().add(0,stockBase);
                        }
                    }else{
                        oldGroup.getStockList().remove(stockBase);
                    }
                    break;
                }
            }
        }

        Update set = Update.update("_id", userId).set("groupList", oldGroupList);
        return mongoTemplate.updateFirst(query, set, CollectStock.class, "collectStock").isUpdateOfExisting();
    }*/

    @Override
    public boolean syncStock2Group(String userId, String stockInfo, List<String> groupIdList) {
        StockBase stockBase = JSON.parseObject(stockInfo, StockBase.class);
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(userId));
        CollectStock collectStock = mongoTemplate.findOne(query, CollectStock.class, "collectStock");
        List<CollectStockGroup> groupList = collectStock.getGroupList();
        for (CollectStockGroup collectStockGroup : groupList) {
            if (groupIdList.contains(collectStockGroup.getGroupId())
                    && !collectStockGroup.getStockList().contains(stockBase)) {
                List<StockBase> stockBaseList = collectStockGroup.getStockList();
                stockBaseList.add(stockBase);
            }
        }
        Update set = Update.update("_id", userId).set("groupList", groupList);
        return mongoTemplate.updateFirst(query, set, CollectStock.class, "collectStock").isUpdateOfExisting();
    }

    @Override
    public CollectStock selectCollectStockDetails(String userId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(userId));
        CollectStock collectStock = mongoTemplate.findOne(query, CollectStock.class, "collectStock");
        if (null == collectStock) {
            collectStock = new CollectStock();
            collectStock.set_id(userId);
            collectStock.setUserId(userId);
            List<CollectStockGroup> groupList = new ArrayList<>();
            CollectStockGroup collectStockGroup = new CollectStockGroup();
            collectStockGroup.setGroupId("Default");
            collectStockGroup.setGroupName("自选");
            groupList.add(collectStockGroup);
            collectStock.setGroupList(groupList);
            try {
                mongoTemplate.insert(collectStock, "collectStock");
            } catch (Exception e) {
                e.printStackTrace();
                return collectStock;
            }
        }
        return collectStock;
    }

    @Override
    public void updateStockSuffix(String userId) {
        Query query = new Query();
        if (userId != null && !userId.equals("")) {
            query.addCriteria(Criteria.where("_id").is(userId));
        }
        List<CollectStock> collectStocks = mongoTemplate.find(query, CollectStock.class, "collectStock");
        for (CollectStock collectStock : collectStocks) {
            List<CollectStockGroup> groupList = collectStock.getGroupList();
            if (groupList == null || groupList.size() == 0)
                continue;
            for (CollectStockGroup collectStockGroup : groupList) {
                if (collectStockGroup == null)
                    continue;
                List<StockBase> stockList = collectStockGroup.getStockList();
                if (stockList == null || stockList.size() == 0)
                    continue;
                for (StockBase stockBase : stockList) {
                    String code = stockBase.getStockCode();
                    stockBase.setTsCode(ParseStockCodeUtil.parseStockCode(code));
                }
            }
            System.out.println(collectStock);
            Query update_query = new Query();
            update_query.addCriteria(Criteria.where("_id").is(collectStock.get_id()));
            Update set = Update.update("_id", collectStock.get_id()).set("groupList", collectStock.getGroupList());
            mongoTemplate.updateFirst(update_query, set, CollectStock.class, "collectStock");

        }
    }

    @Override
    public List<RealTimeSimpleStockData> getCollectStockbylimit(String userId, String groupId, String sort,String type) {
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(userId));
        CollectStock collectStock = mongoTemplate.findOne(query, CollectStock.class, "collectStock");
        //添加过自选
        List<CollectStockGroup> groupList = collectStock.getGroupList();
        List<String> stockchoose=new ArrayList<>();
        List<RealTimeSimpleStockData> returnList = new ArrayList<>();
        List<CollectStockGroup> resultGroupList = new ArrayList<>();
        for (CollectStockGroup stockGroup : groupList) {
            if (stockGroup.getGroupId().equals(groupId)) {
                for(int i=0;i<stockGroup.getStockList().size();i++){
                    stockchoose.add(stockGroup.getStockList().get(i).getTsCode());
                    stockchoose.add(stockGroup.getStockList().get(i).getName());
                }
                resultGroupList.add(stockGroup);
                break;
            }
        }
        for (int i=0;i<stockchoose.size();i+=2){
            Object obj= stringredisTemplate.opsForHash().get("Real_time_Stock_Data",stockchoose.get(i).toLowerCase(Locale.ROOT));
            JSONObject jo=JSON.parseObject((String) obj);
            RealTimeSimpleStockData re=new RealTimeSimpleStockData();
           try {
               re.setChange(jo.getString("change"));
               re.setNewPrice(jo.getString("newPrice"));
               re.setHlPercent(jo.getString("hlPercent"));
               re.setCode(jo.getString("code"));
           }
           catch (Exception e){
               continue;
           }
            re.setName(stockchoose.get(i+1));
            returnList.add(re);
        }
        if(type.equals("1")&&sort.equals("0")){
            Collections.sort(returnList, new Comparator<RealTimeSimpleStockData>() {
                @Override
                public int compare(RealTimeSimpleStockData o1, RealTimeSimpleStockData o2) {
                    return   (int) (Float.parseFloat(o1.getNewPrice())*100-Float.parseFloat(o2.getNewPrice())*100);
                }
            });
        }
        else if(type.equals("1")&&sort.equals("1")){
            Collections.sort(returnList, new Comparator<RealTimeSimpleStockData>() {
                @Override
                public int compare(RealTimeSimpleStockData o1, RealTimeSimpleStockData o2) {
                    return   (int) (Float.parseFloat(o1.getNewPrice())*100-Float.parseFloat(o2.getNewPrice())*100);
                }
            });
            Collections.reverse(returnList);
        }
       else if(type.equals("2")&&sort.equals("0")){
            Collections.sort(returnList, new Comparator<RealTimeSimpleStockData>() {
                @Override
                public int compare(RealTimeSimpleStockData o1, RealTimeSimpleStockData o2) {
                    return   (int) (Float.parseFloat(o1.getChange())*100-Float.parseFloat(o2.getChange())*100);
                }
            });
        }
        else if(type.equals("2")&&sort.equals("1")){
            Collections.sort(returnList, new Comparator<RealTimeSimpleStockData>() {
                @Override
                public int compare(RealTimeSimpleStockData o1, RealTimeSimpleStockData o2) {
                    return   (int) (Float.parseFloat(o1.getChange())*100-Float.parseFloat(o2.getChange())*100);
                }
            });
            Collections.reverse(returnList);
        }
        else if(type.equals("3")&&sort.equals("0")){
            Collections.sort(returnList, new Comparator<RealTimeSimpleStockData>() {
                @Override
                public int compare(RealTimeSimpleStockData o1, RealTimeSimpleStockData o2) {
                    return   (int) (realdataformate(o1.getHlPercent())*100-realdataformate(o2.getHlPercent())*100);
                }
            });
        }
        else if (type.equals("3")&&sort.equals("1")){
            Collections.sort(returnList, new Comparator<RealTimeSimpleStockData>() {
                @Override
                public int compare(RealTimeSimpleStockData o1, RealTimeSimpleStockData o2) {
                    return   (int) (realdataformate(o1.getHlPercent())*100-realdataformate(o2.getHlPercent())*100);
                }
            });
            Collections.reverse(returnList);
        }
       return  returnList;
    }
    private float realdataformate(String s){
        float i=Float.valueOf(s.substring(0,s.length()-1));
        return i;
    }
}
